package parser

import "fmt"

// Visitor 接口定义了访问AST节点的方法
type Visitor interface {
	// VisitNode 访问任意节点
	VisitNode(node Node) error
	
	// 语句访问方法
	VisitSelectStmt(stmt *SelectStmt) error
	VisitInsertStmt(stmt *InsertStmt) error
	VisitUpdateStmt(stmt *UpdateStmt) error
	VisitDeleteStmt(stmt *DeleteStmt) error
	VisitCreateTableStmt(stmt *CreateTableStmt) error
	VisitAlterTableStmt(stmt *AlterTableStmt) error
	VisitDropTableStmt(stmt *DropTableStmt) error
	VisitCreateIndexStmt(stmt *CreateIndexStmt) error
	VisitDropIndexStmt(stmt *DropIndexStmt) error
	VisitCreateViewStmt(stmt *CreateViewStmt) error
	VisitDropViewStmt(stmt *DropViewStmt) error
	VisitGrantStmt(stmt *GrantStmt) error
	VisitRevokeStmt(stmt *RevokeStmt) error
	VisitBeginStmt(stmt *BeginStmt) error
	VisitCommitStmt(stmt *CommitStmt) error
	VisitRollbackStmt(stmt *RollbackStmt) error
	VisitSavepointStmt(stmt *SavepointStmt) error
	VisitReleaseSavepointStmt(stmt *ReleaseSavepointStmt) error
	
	// 表达式访问方法
	VisitColumnRef(expr *ColumnRef) error
	VisitLiteral(expr *Literal) error
	VisitBinaryExpr(expr *BinaryExpr) error
	VisitUnaryExpr(expr *UnaryExpr) error
	VisitFunctionCall(expr *FunctionCall) error
	VisitSubqueryExpr(expr *SubqueryExpr) error
	VisitCaseExpr(expr *CaseExpr) error
	VisitArrayExpr(expr *ArrayExpr) error
	VisitArrayAccess(expr *ArrayAccess) error
	VisitJSONBExpr(expr *JSONBExpr) error
	
	// 其他节点访问方法
	VisitTableRef(ref *TableRef) error
	VisitJoinExpr(expr *JoinExpr) error
	VisitOrderByExpr(expr *OrderByExpr) error
	VisitUpdateExpr(expr *UpdateExpr) error
	VisitWithClause(clause *WithClause) error
	VisitCommonTableExpr(expr *CommonTableExpr) error
}

// BaseVisitor 提供默认的访问器实现
type BaseVisitor struct{}

func (v *BaseVisitor) VisitNode(node Node) error { return nil }
func (v *BaseVisitor) VisitSelectStmt(stmt *SelectStmt) error { return nil }
func (v *BaseVisitor) VisitInsertStmt(stmt *InsertStmt) error { return nil }
func (v *BaseVisitor) VisitUpdateStmt(stmt *UpdateStmt) error { return nil }
func (v *BaseVisitor) VisitDeleteStmt(stmt *DeleteStmt) error { return nil }
func (v *BaseVisitor) VisitCreateTableStmt(stmt *CreateTableStmt) error { return nil }
func (v *BaseVisitor) VisitAlterTableStmt(stmt *AlterTableStmt) error { return nil }
func (v *BaseVisitor) VisitDropTableStmt(stmt *DropTableStmt) error { return nil }
func (v *BaseVisitor) VisitCreateIndexStmt(stmt *CreateIndexStmt) error { return nil }
func (v *BaseVisitor) VisitDropIndexStmt(stmt *DropIndexStmt) error { return nil }
func (v *BaseVisitor) VisitCreateViewStmt(stmt *CreateViewStmt) error { return nil }
func (v *BaseVisitor) VisitDropViewStmt(stmt *DropViewStmt) error { return nil }
func (v *BaseVisitor) VisitGrantStmt(stmt *GrantStmt) error { return nil }
func (v *BaseVisitor) VisitRevokeStmt(stmt *RevokeStmt) error { return nil }
func (v *BaseVisitor) VisitBeginStmt(stmt *BeginStmt) error { return nil }
func (v *BaseVisitor) VisitCommitStmt(stmt *CommitStmt) error { return nil }
func (v *BaseVisitor) VisitRollbackStmt(stmt *RollbackStmt) error { return nil }
func (v *BaseVisitor) VisitSavepointStmt(stmt *SavepointStmt) error { return nil }
func (v *BaseVisitor) VisitReleaseSavepointStmt(stmt *ReleaseSavepointStmt) error { return nil }
func (v *BaseVisitor) VisitColumnRef(expr *ColumnRef) error { return nil }
func (v *BaseVisitor) VisitLiteral(expr *Literal) error { return nil }
func (v *BaseVisitor) VisitBinaryExpr(expr *BinaryExpr) error { return nil }
func (v *BaseVisitor) VisitUnaryExpr(expr *UnaryExpr) error { return nil }
func (v *BaseVisitor) VisitFunctionCall(expr *FunctionCall) error { return nil }
func (v *BaseVisitor) VisitSubqueryExpr(expr *SubqueryExpr) error { return nil }
func (v *BaseVisitor) VisitCaseExpr(expr *CaseExpr) error { return nil }
func (v *BaseVisitor) VisitArrayExpr(expr *ArrayExpr) error { return nil }
func (v *BaseVisitor) VisitArrayAccess(expr *ArrayAccess) error { return nil }
func (v *BaseVisitor) VisitJSONBExpr(expr *JSONBExpr) error { return nil }
func (v *BaseVisitor) VisitTableRef(ref *TableRef) error { return nil }
func (v *BaseVisitor) VisitJoinExpr(expr *JoinExpr) error { return nil }
func (v *BaseVisitor) VisitOrderByExpr(expr *OrderByExpr) error { return nil }
func (v *BaseVisitor) VisitUpdateExpr(expr *UpdateExpr) error { return nil }
func (v *BaseVisitor) VisitWithClause(clause *WithClause) error { return nil }
func (v *BaseVisitor) VisitCommonTableExpr(expr *CommonTableExpr) error { return nil }

// Walk 遍历AST节点
func Walk(visitor Visitor, node Node) error {
	if node == nil {
		return nil
	}
	
	// 首先访问当前节点
	if err := visitor.VisitNode(node); err != nil {
		return err
	}
	
	// 根据节点类型进行特定访问
	switch n := node.(type) {
	case *SelectStmt:
		return walkSelectStmt(visitor, n)
	case *InsertStmt:
		return walkInsertStmt(visitor, n)
	case *UpdateStmt:
		return walkUpdateStmt(visitor, n)
	case *DeleteStmt:
		return walkDeleteStmt(visitor, n)
	case *CreateTableStmt:
		return walkCreateTableStmt(visitor, n)
	case *AlterTableStmt:
		return walkAlterTableStmt(visitor, n)
	case *DropTableStmt:
		return walkDropTableStmt(visitor, n)
	case *CreateIndexStmt:
		return walkCreateIndexStmt(visitor, n)
	case *DropIndexStmt:
		return walkDropIndexStmt(visitor, n)
	case *CreateViewStmt:
		return walkCreateViewStmt(visitor, n)
	case *DropViewStmt:
		return walkDropViewStmt(visitor, n)
	case *GrantStmt:
		return walkGrantStmt(visitor, n)
	case *RevokeStmt:
		return walkRevokeStmt(visitor, n)
	case *BeginStmt:
		return visitor.VisitBeginStmt(n)
	case *CommitStmt:
		return visitor.VisitCommitStmt(n)
	case *RollbackStmt:
		return visitor.VisitRollbackStmt(n)
	case *SavepointStmt:
		return visitor.VisitSavepointStmt(n)
	case *ReleaseSavepointStmt:
		return visitor.VisitReleaseSavepointStmt(n)
	case *ColumnRef:
		return visitor.VisitColumnRef(n)
	case *Literal:
		return visitor.VisitLiteral(n)
	case *BinaryExpr:
		return walkBinaryExpr(visitor, n)
	case *UnaryExpr:
		return walkUnaryExpr(visitor, n)
	case *FunctionCall:
		return walkFunctionCall(visitor, n)
	case *SubqueryExpr:
		return walkSubqueryExpr(visitor, n)
	case *CaseExpr:
		return walkCaseExpr(visitor, n)
	case *ArrayExpr:
		return walkArrayExpr(visitor, n)
	case *ArrayAccess:
		return walkArrayAccess(visitor, n)
	case *JSONBExpr:
		return walkJSONBExpr(visitor, n)
	case *TableRef:
		return walkTableRef(visitor, n)
	case *JoinExpr:
		return walkJoinExpr(visitor, n)
	case *OrderByExpr:
		return walkOrderByExpr(visitor, n)
	case *UpdateExpr:
		return walkUpdateExpr(visitor, n)
	case *WithClause:
		return walkWithClause(visitor, n)
	case *CommonTableExpr:
		return walkCommonTableExpr(visitor, n)
	default:
		return fmt.Errorf("unknown node type: %T", node)
	}
}

// 具体的遍历函数实现

func walkSelectStmt(visitor Visitor, stmt *SelectStmt) error {
	if err := visitor.VisitSelectStmt(stmt); err != nil {
		return err
	}
	
	// 遍历目标列表
	for _, target := range stmt.Targets {
		if err := Walk(visitor, target); err != nil {
			return err
		}
	}
	
	// 遍历FROM子句
	for _, from := range stmt.From {
		if err := Walk(visitor, &from); err != nil {
			return err
		}
	}
	
	// 遍历WHERE条件
	if stmt.Where != nil {
		if err := Walk(visitor, stmt.Where); err != nil {
			return err
		}
	}
	
	// 遍历GROUP BY
	for _, groupBy := range stmt.GroupBy {
		if err := Walk(visitor, groupBy); err != nil {
			return err
		}
	}
	
	// 遍历HAVING条件
	if stmt.Having != nil {
		if err := Walk(visitor, stmt.Having); err != nil {
			return err
		}
	}
	
	// 遍历ORDER BY
	for _, orderBy := range stmt.OrderBy {
		if err := Walk(visitor, &orderBy); err != nil {
			return err
		}
	}
	
	// 遍历LIMIT和OFFSET
	if stmt.Limit != nil {
		if err := Walk(visitor, stmt.Limit); err != nil {
			return err
		}
	}
	if stmt.Offset != nil {
		if err := Walk(visitor, stmt.Offset); err != nil {
			return err
		}
	}
	
	return nil
}

func walkInsertStmt(visitor Visitor, stmt *InsertStmt) error {
	if err := visitor.VisitInsertStmt(stmt); err != nil {
		return err
	}
	
	// 遍历表引用
	if stmt.Table != nil {
		if err := Walk(visitor, stmt.Table); err != nil {
			return err
		}
	}
	
	// 遍历VALUES
	for _, row := range stmt.Values {
		for _, value := range row {
			if err := Walk(visitor, value); err != nil {
				return err
			}
		}
	}
	
	// 遍历SELECT子句
	if stmt.Select != nil {
		if err := Walk(visitor, stmt.Select); err != nil {
			return err
		}
	}
	
	return nil
}

func walkUpdateStmt(visitor Visitor, stmt *UpdateStmt) error {
	if err := visitor.VisitUpdateStmt(stmt); err != nil {
		return err
	}
	
	// 遍历表引用
	if stmt.Table != nil {
		if err := Walk(visitor, stmt.Table); err != nil {
			return err
		}
	}
	
	// 遍历SET子句
	for _, set := range stmt.Set {
		if err := Walk(visitor, &set); err != nil {
			return err
		}
	}
	
	// 遍历WHERE条件
	if stmt.Where != nil {
		if err := Walk(visitor, stmt.Where); err != nil {
			return err
		}
	}
	
	return nil
}

func walkDeleteStmt(visitor Visitor, stmt *DeleteStmt) error {
	if err := visitor.VisitDeleteStmt(stmt); err != nil {
		return err
	}
	
	// 遍历表引用
	if stmt.Table != nil {
		if err := Walk(visitor, stmt.Table); err != nil {
			return err
		}
	}
	
	// 遍历WHERE条件
	if stmt.Where != nil {
		if err := Walk(visitor, stmt.Where); err != nil {
			return err
		}
	}
	
	return nil
}

func walkCreateTableStmt(visitor Visitor, stmt *CreateTableStmt) error {
	return visitor.VisitCreateTableStmt(stmt)
}

func walkAlterTableStmt(visitor Visitor, stmt *AlterTableStmt) error {
	return visitor.VisitAlterTableStmt(stmt)
}

func walkDropTableStmt(visitor Visitor, stmt *DropTableStmt) error {
	return visitor.VisitDropTableStmt(stmt)
}

func walkCreateIndexStmt(visitor Visitor, stmt *CreateIndexStmt) error {
	return visitor.VisitCreateIndexStmt(stmt)
}

func walkDropIndexStmt(visitor Visitor, stmt *DropIndexStmt) error {
	return visitor.VisitDropIndexStmt(stmt)
}

func walkCreateViewStmt(visitor Visitor, stmt *CreateViewStmt) error {
	if err := visitor.VisitCreateViewStmt(stmt); err != nil {
		return err
	}
	
	// 遍历SELECT语句
	if stmt.Select != nil {
		if err := Walk(visitor, stmt.Select); err != nil {
			return err
		}
	}
	
	return nil
}

func walkDropViewStmt(visitor Visitor, stmt *DropViewStmt) error {
	return visitor.VisitDropViewStmt(stmt)
}

func walkGrantStmt(visitor Visitor, stmt *GrantStmt) error {
	return visitor.VisitGrantStmt(stmt)
}

func walkRevokeStmt(visitor Visitor, stmt *RevokeStmt) error {
	return visitor.VisitRevokeStmt(stmt)
}

func walkBinaryExpr(visitor Visitor, expr *BinaryExpr) error {
	if err := visitor.VisitBinaryExpr(expr); err != nil {
		return err
	}
	
	// 遍历左右操作数
	if err := Walk(visitor, expr.Left); err != nil {
		return err
	}
	if err := Walk(visitor, expr.Right); err != nil {
		return err
	}
	
	return nil
}

func walkUnaryExpr(visitor Visitor, expr *UnaryExpr) error {
	if err := visitor.VisitUnaryExpr(expr); err != nil {
		return err
	}
	
	// 遍历操作数
	if err := Walk(visitor, expr.Operand); err != nil {
		return err
	}
	
	return nil
}

func walkFunctionCall(visitor Visitor, expr *FunctionCall) error {
	if err := visitor.VisitFunctionCall(expr); err != nil {
		return err
	}
	
	// 遍历参数
	for _, arg := range expr.Args {
		if err := Walk(visitor, arg); err != nil {
			return err
		}
	}
	
	return nil
}

func walkSubqueryExpr(visitor Visitor, expr *SubqueryExpr) error {
	if err := visitor.VisitSubqueryExpr(expr); err != nil {
		return err
	}
	
	// 遍历子查询
	if expr.Select != nil {
		if err := Walk(visitor, expr.Select); err != nil {
			return err
		}
	}
	
	return nil
}

func walkCaseExpr(visitor Visitor, expr *CaseExpr) error {
	if err := visitor.VisitCaseExpr(expr); err != nil {
		return err
	}
	
	// 遍历CASE表达式
	if expr.Expr != nil {
		if err := Walk(visitor, expr.Expr); err != nil {
			return err
		}
	}
	
	// 遍历WHEN子句
	for _, when := range expr.WhenList {
		if err := Walk(visitor, when.Condition); err != nil {
			return err
		}
		if err := Walk(visitor, when.Result); err != nil {
			return err
		}
	}
	
	// 遍历ELSE子句
	if expr.Else != nil {
		if err := Walk(visitor, expr.Else); err != nil {
			return err
		}
	}
	
	return nil
}

func walkArrayExpr(visitor Visitor, expr *ArrayExpr) error {
	if err := visitor.VisitArrayExpr(expr); err != nil {
		return err
	}
	
	// 遍历数组元素
	for _, element := range expr.Elements {
		if err := Walk(visitor, element); err != nil {
			return err
		}
	}
	
	return nil
}

func walkArrayAccess(visitor Visitor, expr *ArrayAccess) error {
	if err := visitor.VisitArrayAccess(expr); err != nil {
		return err
	}
	
	// 遍历数组和索引
	if err := Walk(visitor, expr.Array); err != nil {
		return err
	}
	if err := Walk(visitor, expr.Index); err != nil {
		return err
	}
	
	return nil
}

func walkJSONBExpr(visitor Visitor, expr *JSONBExpr) error {
	if err := visitor.VisitJSONBExpr(expr); err != nil {
		return err
	}
	
	// 遍历左右操作数
	if err := Walk(visitor, expr.Left); err != nil {
		return err
	}
	if err := Walk(visitor, expr.Right); err != nil {
		return err
	}
	
	return nil
}

func walkTableRef(visitor Visitor, ref *TableRef) error {
	if err := visitor.VisitTableRef(ref); err != nil {
		return err
	}
	
	// 遍历JOIN表达式
	for _, join := range ref.Joins {
		if err := Walk(visitor, &join); err != nil {
			return err
		}
	}
	
	return nil
}

func walkJoinExpr(visitor Visitor, expr *JoinExpr) error {
	if err := visitor.VisitJoinExpr(expr); err != nil {
		return err
	}
	
	// 遍历表引用和条件
	if expr.Table != nil {
		if err := Walk(visitor, expr.Table); err != nil {
			return err
		}
	}
	if expr.Condition != nil {
		if err := Walk(visitor, expr.Condition); err != nil {
			return err
		}
	}
	
	return nil
}

func walkOrderByExpr(visitor Visitor, expr *OrderByExpr) error {
	if err := visitor.VisitOrderByExpr(expr); err != nil {
		return err
	}
	
	// 遍历表达式
	if expr.Expr != nil {
		if err := Walk(visitor, expr.Expr); err != nil {
			return err
		}
	}
	
	return nil
}

func walkUpdateExpr(visitor Visitor, expr *UpdateExpr) error {
	if err := visitor.VisitUpdateExpr(expr); err != nil {
		return err
	}
	
	// 遍历值表达式
	if expr.Value != nil {
		if err := Walk(visitor, expr.Value); err != nil {
			return err
		}
	}
	
	return nil
}

func walkWithClause(visitor Visitor, clause *WithClause) error {
	if err := visitor.VisitWithClause(clause); err != nil {
		return err
	}
	
	// 遍历CTE
	for _, cte := range clause.CTEs {
		if err := Walk(visitor, cte); err != nil {
			return err
		}
	}
	
	return nil
}

func walkCommonTableExpr(visitor Visitor, expr *CommonTableExpr) error {
	if err := visitor.VisitCommonTableExpr(expr); err != nil {
		return err
	}
	
	// 遍历查询
	if expr.Query != nil {
		if err := Walk(visitor, expr.Query); err != nil {
			return err
		}
	}
	
	return nil
}

// 示例访问器实现

// TableCollector 收集所有表名的访问器
type TableCollector struct {
	BaseVisitor
	Tables []string
}

func (tc *TableCollector) VisitTableRef(ref *TableRef) error {
	tc.Tables = append(tc.Tables, ref.Name)
	return nil
}

// ColumnCollector 收集所有列名的访问器
type ColumnCollector struct {
	BaseVisitor
	Columns []string
}

func (cc *ColumnCollector) VisitColumnRef(ref *ColumnRef) error {
	if ref.Table != "" {
		cc.Columns = append(cc.Columns, ref.Table+"."+ref.Column)
	} else {
		cc.Columns = append(cc.Columns, ref.Column)
	}
	return nil
}

// FunctionCollector 收集所有函数调用的访问器
type FunctionCollector struct {
	BaseVisitor
	Functions []string
}

func (fc *FunctionCollector) VisitFunctionCall(call *FunctionCall) error {
	fc.Functions = append(fc.Functions, call.Name)
	return nil
}

// StatementTypeCollector 收集语句类型的访问器
type StatementTypeCollector struct {
	BaseVisitor
	Statements []string
}

func (stc *StatementTypeCollector) VisitSelectStmt(stmt *SelectStmt) error {
	stc.Statements = append(stc.Statements, "SELECT")
	return nil
}

func (stc *StatementTypeCollector) VisitInsertStmt(stmt *InsertStmt) error {
	stc.Statements = append(stc.Statements, "INSERT")
	return nil
}

func (stc *StatementTypeCollector) VisitUpdateStmt(stmt *UpdateStmt) error {
	stc.Statements = append(stc.Statements, "UPDATE")
	return nil
}

func (stc *StatementTypeCollector) VisitDeleteStmt(stmt *DeleteStmt) error {
	stc.Statements = append(stc.Statements, "DELETE")
	return nil
}

func (stc *StatementTypeCollector) VisitCreateTableStmt(stmt *CreateTableStmt) error {
	stc.Statements = append(stc.Statements, "CREATE TABLE")
	return nil
}

func (stc *StatementTypeCollector) VisitAlterTableStmt(stmt *AlterTableStmt) error {
	stc.Statements = append(stc.Statements, "ALTER TABLE")
	return nil
}

func (stc *StatementTypeCollector) VisitDropTableStmt(stmt *DropTableStmt) error {
	stc.Statements = append(stc.Statements, "DROP TABLE")
	return nil
}

// 便利函数

// GetTables 获取AST中的所有表名
func GetTables(node Node) ([]string, error) {
	collector := &TableCollector{}
	if err := Walk(collector, node); err != nil {
		return nil, err
	}
	return collector.Tables, nil
}

// GetColumns 获取AST中的所有列名
func GetColumns(node Node) ([]string, error) {
	collector := &ColumnCollector{}
	if err := Walk(collector, node); err != nil {
		return nil, err
	}
	return collector.Columns, nil
}

// GetFunctions 获取AST中的所有函数调用
func GetFunctions(node Node) ([]string, error) {
	collector := &FunctionCollector{}
	if err := Walk(collector, node); err != nil {
		return nil, err
	}
	return collector.Functions, nil
}

// GetStatementTypes 获取AST中的所有语句类型
func GetStatementTypes(node Node) ([]string, error) {
	collector := &StatementTypeCollector{}
	if err := Walk(collector, node); err != nil {
		return nil, err
	}
	return collector.Statements, nil
}